package com.pureut.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pureut.order.domain.CustomerManagement;
import com.pureut.order.dto.CustomerManagementDto;
import com.pureut.order.dto.CustomerManagementMqDto;
import com.pureut.order.export.CustomerManagementExport;
import com.pureut.order.export.CustomerManagementimportExport;
import com.pureut.order.mapper.CustomerManagementMapper;
import com.pureut.order.service.CustomerManagementService;
import com.pureut.order.util.VariousMqUtil;
import com.pureut.order.vo.CustomerManagementVo;
import com.pureut.order.vo.OrderReviewVo;
import com.sale.common.core.domain.R;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.dict.utils.DictUtils;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.RedisUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.order.api.dto.CustomerBalance;
import com.sale.order.api.dto.CustomerManagementResultDto;
import com.sale.system.api.RemoteCodeService;
import com.sale.system.api.RemoteReviewService;
import com.sale.system.api.RemoteStaffManagementService;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysStaffManagementDto;
import com.sale.system.api.domain.vo.SysAuditHistoryVo;
import com.sale.system.api.model.LoginUser;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 客户实现层
 * @author jack
 */
@Service
@RequiredArgsConstructor
public class CustomerManagementServiceImpl implements CustomerManagementService {

    private final CustomerManagementMapper customerManagementMapper;

    @DubboReference
    private final RemoteCodeService remoteCodeService;

    @DubboReference
    private final RemoteReviewService remoteReviewService;

    @DubboReference
    RemoteStaffManagementService remoteStaffManagementService;


    /**
     * 客户列表
     *
     * @param customerManagementVo
     * @return
     */
    @Override
    public TableDataInfo<CustomerManagementDto> getList(CustomerManagementVo customerManagementVo, PageQuery pageQuery) {
        Page<CustomerManagementDto> page = customerManagementMapper.getCoustomerList(pageQuery.build(), customerManagementVo);
        List<CustomerManagementDto> records = page.getRecords();
        for (CustomerManagementDto entity : records) {
            //销售人员
            if (entity.getAscriptionBy() != null) {
                Long staffId = Long.valueOf(entity.getAscriptionBy());
                R<SysStaffManagementDto> info = remoteStaffManagementService.getInfo(staffId);
                if (info.getData() != null) {
                    entity.setAscriptionByDict(info.getData().getStaffName());
                }
            }
        }
        return TableDataInfo.build(page);
    }

    /**
     * 客户新增
     *
     * @param customerManagementVo
     * @return
     */
    @Override
    public boolean addConverter(CustomerManagementVo customerManagementVo) throws Exception {
        //判断简称是否存在
        CustomerManagement customerManagementOne = customerManagementMapper.selectOne(new QueryWrapper<CustomerManagement>().lambda().eq(CustomerManagement::getCustomerAbbreviation, customerManagementVo.getCustomerAbbreviation()));
        if (customerManagementOne != null) {
            throw new GlobalException("该客户简称已经存在");
        }
        //获取当前登录人信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        CustomerManagement customerManagement = new CustomerManagement();
        customerManagement.setDeptId(loginUser.getDeptId());
        customerManagement.setCustomerName(customerManagementVo.getCustomerName());
        customerManagement.setCustomerAbbreviation(customerManagementVo.getCustomerAbbreviation());
        String authorityCoding = remoteCodeService.authorityCoding("order:customer:list");
        if (authorityCoding == null) {
            throw new GlobalException("未进行单据配置,单据编码生成失败");
        }
        customerManagement.setCustomerNum(authorityCoding);
        customerManagement.setCreateBy(loginUser.getUsername());
        customerManagement.setContactsBy(customerManagementVo.getContactsBy());
        customerManagement.setInvoicingInformation(customerManagementVo.getInvoicingInformation());
        customerManagement.setBusinessLicense(customerManagementVo.getBusinessLicense());
        customerManagement.setAuditStatus(1);
        customerManagement.setCreateTime(new Date());
        customerManagement.setCustomerCategoryCode(customerManagementVo.getCustomerCategoryCodeName());
        customerManagement.setRatepayerNumber(customerManagementVo.getRatepayerNumber());
        customerManagement.setContactsPhone(customerManagementVo.getContactsPhone());
        customerManagement.setConsigneeBy(customerManagementVo.getConsigneeBy());
        customerManagement.setConsigneePhone(customerManagementVo.getConsigneePhone());
        customerManagement.setConsigneeAddress(customerManagementVo.getConsigneeAddress());
        customerManagement.setBankDeposit(customerManagementVo.getBankDeposit());
        customerManagement.setOpenAccount(customerManagementVo.getOpenAccount());
        customerManagement.setRemark(customerManagementVo.getRemark());
        if (customerManagementVo.getAscriptionBy() != 0) {
            customerManagement.setAscriptionBy(customerManagementVo.getAscriptionBy());
        }

        int insert = customerManagementMapper.insert(customerManagement);
        //mq发送消息
        CustomerManagementMqDto customerManagementMqDto = new CustomerManagementMqDto();
        BeanUtils.copyProperties(customerManagement, customerManagementMqDto);
        //租户id
        String userIdStr = LoginHelper.getUserIdStr();
        String tenantId = RedisUtils.getCacheObject(userIdStr);
        customerManagementMqDto.setTenantId(Long.parseLong(tenantId));
        customerManagementMqDto.setId(customerManagement.getId());
        VariousMqUtil.customerManagementMqSend(customerManagementMqDto);
        return insert > 0;
    }

    /**
     * 冻结客户
     *
     * @param id
     * @return
     */
    @Override
    public boolean frozenSupplier(Long id) {
        CustomerManagement customerManagement = customerManagementMapper.selectById(id);
        if (customerManagement.getAuditStatus() == 4) {
            customerManagement.setAuditStatus(5);
            return customerManagementMapper.updateById(customerManagement) > 0;
        } else {
            throw new GlobalException("只能冻结启用的客户");
        }

    }

    /**
     * 客户解冻
     *
     * @param id
     * @return
     */
    @Override
    public boolean thawSupplier(Long id) {
        CustomerManagement customerManagement = customerManagementMapper.selectById(id);
        if (customerManagement.getAuditStatus() == 5) {
            customerManagement.setAuditStatus(4);
            return customerManagementMapper.updateById(customerManagement) > 0;
        } else {
            throw new GlobalException("只能解冻已冻结的数据");
        }

    }

    /**
     * 撤销审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean revokeApproval(Long id) {
        CustomerManagement customerManagement = customerManagementMapper.selectById(id);
        if (customerManagement.getAuditStatus() == 2) {
            customerManagement.setAuditStatus(1);
            return customerManagementMapper.updateById(customerManagement) > 0;
        } else {
            throw new GlobalException("只能撤销待审核的数据");
        }

    }

    /**
     * 客户信息导出
     *
     * @param customerManagementVo
     * @return
     */
    @Override
    public List<CustomerManagementExport> getInfoExport(CustomerManagementVo customerManagementVo) {
        List<CustomerManagementExport> exportList;
        //获取客户状态缓存字典数据
        List<SysDictData> array = DictUtils.getDictCache("customer_status");
        Map<String, String> actualMap = array.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取客户等级缓存字典数据
        List<SysDictData> levelArray = DictUtils.getDictCache("customer_level");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        if (customerManagementVo.getIdStr() == null) {
            exportList = customerManagementMapper.getExportList(customerManagementVo);
        } else {
            List<String> idList = Arrays.asList(customerManagementVo.getIdStr().split(","));
            exportList = customerManagementMapper.getDataByIdStr(idList);
        }
        for (CustomerManagementExport entity : exportList) {
            //状态
            entity.setAuditStatus(actualMap.get(entity.getAuditStatus()));
            //等级
            entity.setCustomerLevel(levelMap.get(entity.getCustomerLevel()));
            //归属人
            if (entity.getAscriptionBy() != null) {
                String ascriptionBy = entity.getAscriptionBy();
//                entity.setAscriptionBy(feignService.getUserName(Long.valueOf(ascriptionBy)));
            }
        }
        return exportList;
    }


    /**
     * 导入客户
     *
     * @param coCustomer
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importMouldData(List<CustomerManagementimportExport> coCustomer) {
        if (coCustomer.size() == 0) {
            throw new GlobalException("导入客户信息不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        //获取客户等级缓存字典数据
        List<SysDictData> levelArray = DictUtils.getDictCache("customer_level");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (CustomerManagementimportExport mouldModelExport : coCustomer) {
            CustomerManagement customerManagement = new CustomerManagement();
            try {
                //赋值
                customerManagement.setCustomerName(mouldModelExport.getCustomerName());
                //判断简称是否存在
                CustomerManagement customerManagementOne = customerManagementMapper.selectById(new QueryWrapper<CustomerManagement>().lambda().eq(CustomerManagement::getCustomerAbbreviation, mouldModelExport.getCustomerAbbreviation()));
                if (customerManagementOne != null) {
                    throw new GlobalException("该客户简称已经存在");
                }
                customerManagement.setCustomerAbbreviation(mouldModelExport.getCustomerAbbreviation());
                String authorityCoding = remoteCodeService.authorityCoding("order:customer:list");
                if (authorityCoding == null) {
                    throw new GlobalException("未进行单据配置,单据编码生成失败");
                }
                customerManagement.setCustomerNum(authorityCoding);
                //客户等级
                for (Map.Entry<String, String> entry : levelMap.entrySet()) {
                    if (entry.getValue().equals(mouldModelExport.getCustomerLevel())) {
                        customerManagement.setCustomerLevel(Integer.parseInt(entry.getKey()));
                        break;
                    }
                }
                //联系人
                customerManagement.setContactsBy(mouldModelExport.getContactsBy());
                customerManagement.setContactsInformation(mouldModelExport.getContactsInformation());
                //判断归属人是否存在
                String userName = mouldModelExport.getAscriptionBy();
//                if (userName != null) {
//                    AjaxResult byUserName = feignService.getByUserName(userName);
//                    SysUser data = JSON.parseObject(JSON.toJSONString(byUserName.get("data")), SysUser.class);
//                    if (data.getUserId() == null) {
//                        customerManagement.setAscriptionBy(0);
//                    } else {
//                        customerManagement.setAscriptionBy(data.getUserId());
//                    }
//                }
                //获取当前登录人信息
                LoginUser loginUser = LoginHelper.getLoginUser();
                customerManagement.setCreateBy(loginUser.getUsername());
                customerManagement.setAuditStatus(1);
                customerManagement.setCustomerAddress(mouldModelExport.getCustomerAddress());
                customerManagement.setCreateTime(new Date());
                customerManagement.setRemark(mouldModelExport.getRemark());
                customerManagement.setDeptId(loginUser.getDeptId());
                customerManagementMapper.insert(customerManagement);

                successNum++;
                successMsg.append(successNum).append("、客户信息 ").append(mouldModelExport.getCustomerName()).append(" 导入成功");

            } catch (Exception e) {
                failureNum++;
                String msg = failureNum + "、客户 " + mouldModelExport.getCustomerName() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new GlobalException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }

        return successMsg.toString();
    }

    /**
     * 查看客户信息
     *
     * @param id
     * @return
     */
    @Override
    public CustomerManagementDto getCustomerById(Long id) {

        CustomerManagementDto customerManagementById = customerManagementMapper.getCustomerManagementById(id);
        //销售人员
        if (customerManagementById.getAscriptionBy() != null) {
            Long staffId = Long.valueOf(customerManagementById.getAscriptionBy());
            R<SysStaffManagementDto> info = remoteStaffManagementService.getInfo(staffId);
            if (info.getData() != null) {
                customerManagementById.setAscriptionByDict(info.getData().getStaffName());
            }
        }
        return customerManagementById;
    }

    /**
     * 删除客户
     *
     * @param ids
     * @return
     */
    @Override
    public boolean getDeleteByIds(String ids) throws Exception {
        List<CustomerManagement> customerManagementsList = new ArrayList<>();
        if (ids != null) {
            List<String> stringIds = Arrays.asList(ids.split(","));
            //获取客户列表
            List<CustomerManagement> customerManagements = customerManagementMapper.selectBatchIds(stringIds);

            for (CustomerManagement entity : customerManagements) {
                if (entity.getAuditStatus() == 1) {
                    throw new GlobalException("数据启用中，不允许删除");
                }
                customerManagementsList.add(entity);
            }
        } else {
            throw new GlobalException("至少选择一条数据");
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (CustomerManagement entity : customerManagementsList) {
            stringBuilder.append(entity.getId()).append(",");
        }
        StringBuilder stringBuilder1 = stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        //mq同步删除客户
        CustomerManagementMqDto customerManagementMqDto = new CustomerManagementMqDto();
        customerManagementMqDto.setIdStr(stringBuilder1.toString());
        VariousMqUtil.customerManagementMqSendDelete(customerManagementMqDto);
        return customerManagementMapper.deleteBatchIds(customerManagementsList) > 0;
    }

    /**
     * 提交审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean reivewSubmit(Long id) {
        CustomerManagement customerManagement = customerManagementMapper.selectById(id);
        if (customerManagement.getAuditStatus() == 1) {
            customerManagement.setAuditStatus(2);
            return customerManagementMapper.updateById(customerManagement) > 0;
        } else {
            throw new GlobalException("只能提交待审核的数据");
        }

    }


    /**
     * 修改客户
     *
     * @param customerManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCustomerById(CustomerManagementVo customerManagementVo) throws Exception {
        CustomerManagement customerManagement = customerManagementMapper.selectById(customerManagementVo.getId());
        BeanUtils.copyProperties(customerManagementVo, customerManagement);
        //mq发送消息
        CustomerManagementMqDto customerManagementMqDto = new CustomerManagementMqDto();
        BeanUtils.copyProperties(customerManagement, customerManagementMqDto);
        VariousMqUtil.customerManagementMqSend(customerManagementMqDto);
        return customerManagementMapper.updateById(customerManagement) > 0;
    }

    /**
     * 客户审核
     *
     * @param orderReviewVo
     * @return
     */
    @Override
    public boolean customerReview(OrderReviewVo orderReviewVo) throws Exception {
        //获取当前登录人信息
        CustomerManagement customerManagement = customerManagementMapper.selectById(orderReviewVo.getId());
        if (customerManagement.getAuditStatus() == 2 || customerManagement.getAuditStatus() == 3) {
            String perms = "order:sale:customer:review";
            int isAdopt = orderReviewVo.getIsAdopt();
            String auditDoc = customerManagement.getCustomerNum();
            String auditRemarks = orderReviewVo.getReviewComments();
            Long userId = LoginHelper.getUserId();
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            sysAuditHistoryVo.setPerms(perms);
            sysAuditHistoryVo.setAuditType(2);
            sysAuditHistoryVo.setAuditState(isAdopt);
            sysAuditHistoryVo.setAuditRemarks(auditRemarks);
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setUserId(userId);
            int data = remoteReviewService.getSequence(sysAuditHistoryVo);
            if (data == 0) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (orderReviewVo.getIsAdopt() == 1) {
                if (data == 1) {
                    customerManagement.setAuditStatus(4);
                    return customerManagementMapper.updateById(customerManagement) > 0;
                } else if (data == 2) {
                    customerManagement.setAuditStatus(3);
                    return customerManagementMapper.updateById(customerManagement) > 0;
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    customerManagement.setAuditStatus(6);
                    return customerManagementMapper.updateById(customerManagement) > 0;
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("只能对待审核和审核中的数据进行处理");
        }
    }

    /**
     * 通过客户名称获取客户id
     *
     * @param customerName
     * @return
     */
    @Override
    public CustomerManagement getCustomerId(String customerName) {
        return customerManagementMapper.getCustomerId(customerName);
    }

    /**
     * 修改客户启用状态
     *
     * @param customerManagementVo
     * @return
     */
    @Override
    public boolean updateStatus(CustomerManagementVo customerManagementVo) {
        CustomerManagement customerManagement = customerManagementMapper.selectById(customerManagementVo.getId());
        customerManagement.setAuditStatus(Integer.parseInt(customerManagementVo.getAuditStatus()));
        return customerManagementMapper.updateById(customerManagement) > 0;
    }

    /**
     * 获取启用状态客户列表
     *
     * @return
     */
    @Override
    public List<CustomerManagementDto> getOpenCustomer() {

        return customerManagementMapper.selectOpenCustomerList();
    }

    /**
     * 通过编码获取客户信息
     *
     * @param customerCode
     * @return
     */
    @Override
    public CustomerManagementResultDto getCustomerByCode(String customerCode) {
        CustomerManagementResultDto customerManagementResultDto = new CustomerManagementResultDto();
        CustomerManagement customerManagement = customerManagementMapper.selectOne(new QueryWrapper<CustomerManagement>().lambda().eq(CustomerManagement::getCustomerNum, customerCode));
        BeanUtils.copyProperties(customerManagement, customerManagementResultDto);
        return customerManagementResultDto;
    }

    /**
     * 通过客户名称获取客户编码(财务模块使用)
     */
    @Override
    public String getCodeByCustomerName(String customerName) {
        return customerManagementMapper.getCodeByCustomerName(customerName);
    }

    /**
     * 通过客户编码更新余额
     */
    @Override
    public boolean updateClientBalance(CustomerBalance customerBalance) {
        return customerManagementMapper.updateClientBalance(customerBalance);
    }
}
